﻿using System;
using System.Collections.Generic;
using System.Xml;

namespace IniFileManager
{
	/// <summary>
	/// Class representing inner structure of a section 
	/// within ini schema defined by library user.
	/// </summary>
	internal sealed class IniSectionSchema
	{
		private const string periodedString = "{0}.{1}";
		private readonly string name;
		private readonly bool isRequired;
		private readonly Dictionary<string, IniPropertySchema> properties;

		/// <summary>
		/// Creates "IniSectionSchema" from xml node in ini schema xml representation.
		/// </summary>
		/// <param name="sectionNode">Ini section schema xml node.</param>
		/// <exception cref="System.FormatException">Trown if is provided xml node not valid section node.</exception>
		internal IniSectionSchema( XmlNode sectionNode )
		{
			// Embedded "IniSchema.xsd"'s definition guarantees existence and format of these attributes:
			this.name = sectionNode.Attributes[IniSchemaXsd.ATTRIBUTE_NAME].Value;
			this.isRequired = bool.Parse( sectionNode.Attributes[IniSchemaXsd.ATTRIBUTE_REQUIRED].Value );
			this.properties = new Dictionary<string, IniPropertySchema>();

			// Embedded "IniSchema.xsd"'s definition guarantees that every child of "section" is "property":
			XmlNodeList propertyNodes = sectionNode.ChildNodes;
			foreach( XmlNode propertyNode in propertyNodes )
			{
				try
				{
					// In case of semantical exceptions in "propertyNode" we can expect 
					// "FormatException" while trying to construct "IniPropertySchema" from "propertyNode".
					IniPropertySchema property = new IniPropertySchema( propertyNode );
					properties.Add( property.Name, property );
				}
				catch( FormatException e )
				{
					throw new FormatException( String.Format( periodedString, this.name, e.Message ) );
				}
			}
		}

		/// <summary>
		/// Unique section's name within ini schema.
		/// </summary>
		internal string Name
		{
			get
			{
				return this.name;
			}
		}
		/// <summary>
		/// Boolean representing wheather is section required within ini schema.
		/// </summary>
		internal bool IsRequired
		{
			get
			{
				return this.isRequired;
			}
		}
		/// <summary>
		/// Hash map of property within.
		/// </summary>
		internal Dictionary<string, IniPropertySchema> Properties
		{
			get
			{
				return this.properties;
			}
		}

	}
}
